#include "CH395CMD.h"
uint8_t     dump[2048];
uint32_t    net_comunication_overflow=0;
//-------------------------------------------------------------------------------------
// net_overflow_incr()
// 定时器回调，overflow计数增加
//-------------------------------------------------------------------------------------
void net_overflow_incr(void)
{
    net_comunication_overflow ++ ;
}
//-------------------------------------------------------------------------------------
// net_io_read
// 用于读取数据底层驱动
//-------------------------------------------------------------------------------------
bool net_io_transaction(uint8_t *data, uint16_t length)
{
  uint32_t   *net_io        = (uint32_t*) (0x60000000);
  uint32_t   *net_rio       = (uint32_t*) (0x60000000);
  uint32_t   *rcv_length    = (uint32_t*) (0x60008000);  //接收数据长度寄存器地址
  uint16_t   transmit_length=0;
  bool       ret = false;

  for(int i=0; i<length; i++)
  {
    *net_io = data[i];
  }

  net_comunication_overflow = 0;
  while((transmit_length<length)&&(net_comunication_overflow<10))  //等待指令完成或超时100ms
  {
    transmit_length = *rcv_length;
  }
  ret = (net_comunication_overflow<10);

  for(int i=0; i<transmit_length; i++)                   //读取接收数据
  {
     data[i] =  *net_rio;
  }
  
  return ret;
}

//-------------------------------------------------------------------------------------
// ch395_get_ic_ver
// 用于读取ic 版本
//-------------------------------------------------------------------------------------
uint8_t ch395_get_ic_ver()
{
    uint8_t  buffer[2];
    buffer[0] = CMD01_GET_IC_VER;
    buffer[1] = 0xff;
    net_io_transaction(buffer,2);
    return buffer[1];
}

//-------------------------------------------------------------------------------------
// ch395_check_exist
// 用于检测ch395是否存在，返回数据是输入数据的按位取反
//-------------------------------------------------------------------------------------
uint8_t ch395_check_exist(uint8_t datain)
{
    uint8_t  buffer[3];
    buffer[0] = CMD11_CHECK_EXIST;
    buffer[1] = datain;
    buffer[2] = 0xff;
    net_io_transaction(buffer,3);
    return buffer[2];
}

//-------------------------------------------------------------------------------------
// ch395_set_ip_addr
// 设置ip
//-------------------------------------------------------------------------------------
bool ch395_set_ip_addr(uint8_t* ipaddr)
{
    uint8_t  buffer[5];
    buffer[0] = CMD40_SET_IP_ADDR;
    memcpy(buffer+1,ipaddr,4);
    return(net_io_transaction(buffer,5));
}

//-------------------------------------------------------------------------------------
// ch395_set_gwip_addr 
// 设置网关
//-------------------------------------------------------------------------------------
bool ch395_set_gwip_addr(uint8_t* ipaddr)
{
    uint8_t  buffer[5];
    buffer[0] = CMD40_SET_GWIP_ADDR;
    memcpy(buffer+1,ipaddr,4);
    return(net_io_transaction(buffer,5));
}

//-------------------------------------------------------------------------------------
// ch395_set_mask_addr 
// 设置子网掩码
//-------------------------------------------------------------------------------------
bool ch395_set_mask_addr(uint8_t* ipaddr)
{
    uint8_t  buffer[5];
    buffer[0] = CMD40_SET_MASK_ADDR;
    memcpy(buffer+1,ipaddr,4);
    return(net_io_transaction(buffer,5));
}

//-------------------------------------------------------------------------------------
// ch395_get_cmd_status 
// 获取状态
//-------------------------------------------------------------------------------------
uint8_t ch395_get_cmd_status()
{
    uint8_t  buffer[2];
    buffer[0] = CMD01_GET_CMD_STATUS;
    buffer[1] = 0xff;
    net_io_transaction(buffer,2);
    return buffer[1];
}

//-------------------------------------------------------------------------------------
// ch395_init_ch395 
// 初始化ch395
//-------------------------------------------------------------------------------------
bool ch395_init_ch395()
{
    uint8_t  buffer[1];
    buffer[0] = CMD0W_INIT_CH395;
    return(net_io_transaction(buffer,1));
}

//-------------------------------------------------------------------------------------
// ch395_reset_all
// 用于复位ch395
//-------------------------------------------------------------------------------------
bool ch395_reset_all()
{
    uint8_t  buffer[1];
    buffer[0] = CMD00_RESET_ALL;
    return(net_io_transaction(buffer,1));
}

//-------------------------------------------------------------------------------------
// ch395_set_keep_live_sn 
// 设置keep live功能开启
//-------------------------------------------------------------------------------------
bool ch395_set_keep_live_sn(uint8_t sn, uint8_t cmd)
{
    uint8_t  buffer[3];
    buffer[0] = CMD20_SET_KEEP_LIVE_SN;
    buffer[1] = sn;
    buffer[2] = cmd;
    return(net_io_transaction(buffer,3));
}

//-------------------------------------------------------------------------------------
// ch395_set_keep_live_cnt 
// 设置keep live计数
//-------------------------------------------------------------------------------------
bool ch395_set_keep_live_cnt(uint8_t cnt)
{
    uint8_t  buffer[2];
    buffer[0] = CMD10_SET_KEEP_LIVE_CNT;
    buffer[1] = cnt;
    return(net_io_transaction(buffer,2));
}

//-------------------------------------------------------------------------------------
// ch395_set_keep_live_idle
// 设置keep live 空闲时间，单位ms
//-------------------------------------------------------------------------------------
bool ch395_set_keep_live_idle(uint32_t idle)
{
    uint8_t  buffer[5];
    buffer[0] = CMD40_SET_KEEP_LIVE_IDLE;
    buffer[1] = idle;
    buffer[2] = idle>>8;
    buffer[3] = idle>>16;
    buffer[4] = idle>>24;
    return(net_io_transaction(buffer,5));
}

//-------------------------------------------------------------------------------------
// ch395_set_keep_live_intvl 
// 设置keep live 间隔时间，单位ms
//-------------------------------------------------------------------------------------
bool ch395_set_keep_live_intvl(uint32_t intvl)
{
    uint8_t  buffer[5];
    buffer[0] = CMD40_SET_KEEP_LIVE_INTVL;
    buffer[1] = intvl;
    buffer[2] = intvl>>8;
    buffer[3] = intvl>>16;
    buffer[4] = intvl>>24;
    return(net_io_transaction(buffer,5));
}

//-------------------------------------------------------------------------------------
// ch395_set_ip_addr_sn  
// 设置目标ip地址
//-------------------------------------------------------------------------------------
bool ch395_set_ip_addr_sn(uint8_t sn, uint8_t *ipaddr)
{
    uint8_t  buffer[6];
    buffer[0] = CMD50_SET_IP_ADDR_SN;
    buffer[1] = sn;
    memcpy(buffer+2,ipaddr,4);
    return(net_io_transaction(buffer,6));
}


//-------------------------------------------------------------------------------------
// ch395_set_proto_type_sn  
// 设置协议类型
//-------------------------------------------------------------------------------------
bool ch395_set_proto_type_sn(uint8_t sn, uint8_t prototype)
{
    uint8_t  buffer[3];
    buffer[0] = CMD20_SET_PROTO_TYPE_SN;
    buffer[1] = sn;
    buffer[2] = prototype;
    return(net_io_transaction(buffer,3));
}


//-------------------------------------------------------------------------------------
// ch395_set_des_port_sn  
// 设置目的端口号
//-------------------------------------------------------------------------------------
bool ch395_set_des_port_sn(uint8_t sn, uint16_t port)
{
    uint8_t  buffer[4];
    buffer[0] = CMD30_SET_DES_PORT_SN;
    buffer[1] = sn;
    buffer[2] = port;
    buffer[3] = port>>8;
    return(net_io_transaction(buffer,4));
}

//-------------------------------------------------------------------------------------
// ch395_set_sour_port_sn  
// 设置源端口号
//-------------------------------------------------------------------------------------
bool ch395_set_sour_port_sn(uint8_t sn, uint16_t port)
{
    uint8_t  buffer[4];
    buffer[0] = CMD30_SET_SOUR_PORT_SN;
    buffer[1] = sn;
    buffer[2] = port;
    buffer[3] = port>>8;
    return(net_io_transaction(buffer,4));
}

//-------------------------------------------------------------------------------------
// ch395_set_ttl  
// 设置源端口号
//-------------------------------------------------------------------------------------
bool ch395_set_ttl(uint8_t sn, uint8_t ttl)
{
    uint8_t  buffer[3];
    buffer[0] = CMD20_SET_TTL;
    buffer[1] = sn;
    buffer[2] = ttl;
    return(net_io_transaction(buffer,3));
}

//-------------------------------------------------------------------------------------
// ch395_close_socket_sn   
// 关闭socket n
//-------------------------------------------------------------------------------------
bool ch395_close_socket_sn(uint8_t sn)
{
    uint8_t  buffer[2];
    buffer[0] = CMD1W_CLOSE_SOCKET_SN;
    buffer[1] = sn;
    return(net_io_transaction(buffer,2));
}

//-------------------------------------------------------------------------------------
// ch395_open_socket_sn   
// 打开socket n
//-------------------------------------------------------------------------------------
bool ch395_open_socket_sn(uint8_t sn)
{
    uint8_t  buffer[2];
    buffer[0] = CMD1W_OPEN_SOCKET_SN;
    buffer[1] = sn;
    return(net_io_transaction(buffer,2));
}

//-------------------------------------------------------------------------------------
// ch395_tcp_connect_sn   
// 打开socket n tcp连接
//-------------------------------------------------------------------------------------
bool ch395_tcp_connect_sn(uint8_t sn)
{
    uint8_t  buffer[2];
    buffer[0] = CMD1W_TCP_CONNECT_SN;
    buffer[1] = sn;
    return(net_io_transaction(buffer,2));
}

//-------------------------------------------------------------------------------------
// ch395_get_glob_int_status_all   
// 获取中断状态
//-------------------------------------------------------------------------------------
uint16_t ch395_get_glob_int_status_all()
{
    uint8_t  buffer[3];
    uint16_t ret;
    buffer[0] = CMD02_GET_GLOB_INT_STATUS_ALL;
    buffer[1] = 0xff;
    buffer[2] = 0xff;
    net_io_transaction(buffer,3);
    ret = (buffer[2]<<8) + buffer[1];
    return ret;
}

//-------------------------------------------------------------------------------------
// ch395_get_int_status_sn    
// 获取socket中断状态
//-------------------------------------------------------------------------------------
uint8_t ch395_get_int_status_sn(uint8_t sn)
{
    uint8_t  buffer[3];
    buffer[0] = CMD11_GET_INT_STATUS_SN;
    buffer[1] = sn;
    buffer[2] = 0xff;
    net_io_transaction(buffer,3);
    return buffer[2];
}

//-------------------------------------------------------------------------------------
// ch395_get_recv_len_sn    
// 获取接收缓冲区长度
//-------------------------------------------------------------------------------------
uint16_t ch395_get_recv_len_sn(uint8_t sn)
{
    uint8_t  buffer[4];
    uint16_t ret;
    buffer[0] = CMD12_GET_RECV_LEN_SN;
    buffer[1] = sn;
    buffer[2] = 0xff;
    buffer[3] = 0xff;
    net_io_transaction(buffer,4);
    ret = (buffer[3]<<8) + buffer[2];
    return ret;
}

//-------------------------------------------------------------------------------------
// ch395_get_recv_buf_sn    
// 获取接收缓冲区长度
//-------------------------------------------------------------------------------------
bool ch395_get_recv_buf_sn(uint8_t sn, uint16_t len, uint8_t* pbuf)
{
    bool ret=false;
    memset(dump,0xff,len+4);
    dump[0] = CMD30_READ_RECV_BUF_SN;
    dump[1] = sn;
    dump[2] = len;
    dump[3] = len>>8;
    ret = net_io_transaction(dump,len+4);
    memcpy(pbuf, dump+4, len);
    return ret;
}

//-------------------------------------------------------------------------------------
// ch395_write_send_buf_sn    
// 发送数据
//-------------------------------------------------------------------------------------
bool ch395_write_send_buf_sn(uint8_t sn, uint16_t len, uint8_t* pbuf)
{
    memcpy(dump+4, pbuf,len);
    dump[0] = CMD30_WRITE_SEND_BUF_SN;
    dump[1] = sn;
    dump[2] = len;
    dump[3] = len>>8;
    return(net_io_transaction(dump,len+4));
}